package com.fengwk.support.util;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.jsoup.Jsoup;
import org.jsoup.Connection;
import org.jsoup.Connection.Response;
import org.jsoup.nodes.Document;

import com.fengwk.support.exception.BaseException;
import com.fengwk.support.util.LoggerUtils.Logger;

public class JsoupUtils {

	private static final Logger LOG = LoggerUtils.getLogger(JsoupUtils.class);
	
	private JsoupUtils() {
		throw new BaseException("can not instance " + getClass());
	}
	
	public static Document getDocumentCycle(String url, Integer timeout, String cookieUrl, Integer cookiePullCount) {
		Document document = null;
		try {
			document = getDocument(url, timeout, cookieUrl, cookiePullCount);
		} catch (IOException e) {
		    LOG.error(e);
			return getDocumentCycle(url, timeout, cookieUrl, cookiePullCount);
		}
		return document;
	}
	
	public static Document getDocument(String url, Integer timeout, String cookieUrl, Integer cookiePullCount) throws IOException {
		long begin = System.currentTimeMillis();
		Connection connection = connectionTimeout(Jsoup.connect(url), timeout).ignoreContentType(true);
		Map<String, String> cookies = getCookies(cookieUrl, cookiePullCount, timeout);
		if(cookies != null) connection.cookies(cookies);
		Document document = connection.get();
		LOG.debug("get ==> " + url + "; execute ==> " + (System.currentTimeMillis() - begin));
		return document;
	}
	
	public static Map<String, String> autoCookie(Map<String, String> cookies) {
		Map<String, String> cookieHeader = new HashMap<String, String>();
		if(MapUtils.isNotBlank(cookies)) {
			StringBuffer sb = new StringBuffer();
			for(String key: cookies.keySet()) {
				sb.append(key + "=" + cookies.get(key) + ";");
			}
			if(sb.length() > 0) {
				cookieHeader.put("Cookie", sb.toString());
			}
		}
		return cookieHeader;
	}
	
	public static Map<String, String> getCookies(String url, Integer count, Integer timeout) {
		Map<String, String> cookiePool = new HashMap<String, String>();
		if(StringUtils.isBlank(url) || count == null) {
			return null;
		}
		for(int i = 0; i < count; i ++) {
			Map<String, String> cookiesBuf = getCookies(url, timeout, cookiePool);
			cookiePool.putAll(cookiesBuf);
		}
		return cookiePool;
	}
	
	private static Map<String, String> getCookies(String url, Integer timeout, Map<String, String> cookies) {
		Response response = null;
		try {
			Connection connection = connectionTimeout(Jsoup.connect(url), timeout);
			if(MapUtils.isNotBlank(cookies)) {
				connection = connection.cookies(cookies);
			}
			response = connection.execute();
		} catch (IOException e) {
			LOG.error(e);
			return getCookies(url, timeout, cookies);
		}
		return response.cookies();
	}
	
	private static Connection connectionTimeout(Connection connection, Integer timeout) {
		if(connection != null && timeout != null) {
			connection.timeout(10000);
		}
		return connection;
	}
	
}
